{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "1.Approximate_a_function.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "machine_shape": "hm",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/jdtoscano94/Learning-PINNs-in-Pytorch/blob/main/1_Approximate_a_function.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Libraries"
      ],
      "metadata": {
        "id": "Y61YA90-WIZ1"
      }
    },
    {
      "cell_type": "code",
      "source": [
        " ! pip install pyDOE"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "WZrPCr9GWEAJ",
        "outputId": "dc7953c2-0fbd-4622-b789-55b20e682e97"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: pyDOE in /usr/local/lib/python3.7/dist-packages (0.3.8)\n",
            "Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from pyDOE) (1.4.1)\n",
            "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from pyDOE) (1.21.5)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import torch\n",
        "import torch.autograd as autograd         # computation graph\n",
        "from torch import Tensor                  # tensor node in the computation graph\n",
        "import torch.nn as nn                     # neural networks\n",
        "import torch.optim as optim               # optimizers e.g. gradient descent, ADAM, etc.\n",
        "\n",
        "import matplotlib.pyplot as plt\n",
        "import matplotlib.gridspec as gridspec\n",
        "from mpl_toolkits.axes_grid1 import make_axes_locatable\n",
        "from mpl_toolkits.mplot3d import Axes3D\n",
        "import matplotlib.ticker\n",
        "from sklearn.model_selection import train_test_split\n",
        "\n",
        "import numpy as np\n",
        "import time\n",
        "from pyDOE import lhs         #Latin Hypercube Sampling\n",
        "import scipy.io\n",
        "\n",
        "#Set default dtype to float32\n",
        "torch.set_default_dtype(torch.float)\n",
        "\n",
        "#PyTorch random number generator\n",
        "torch.manual_seed(1234)\n",
        "\n",
        "# Random number generators in other libraries\n",
        "np.random.seed(1234)\n",
        "\n",
        "# Device configuration\n",
        "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
        "\n",
        "print(device)\n",
        "\n",
        "if device == 'cuda': \n",
        "    print(torch.cuda.get_device_name()) \n"
      ],
      "metadata": {
        "id": "OdYMzuSDi7Js",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "ca95dc62-bd0f-4e6f-bc8a-ecb0daed2226"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "cuda\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Device configuration\n",
        "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
        "\n",
        "print(device)\n",
        "\n",
        "if device == 'cuda': \n",
        "    print(torch.cuda.get_device_name()) "
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Vr9AWHqfQcC6",
        "outputId": "3c327fe2-c396-4be3-9479-6fccf059c215"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "cuda\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Tunning Parameters"
      ],
      "metadata": {
        "id": "9zDgeIFblwMX"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "steps=20000\n",
        "lr=1e-3"
      ],
      "metadata": {
        "id": "CMiA3ozQlyav"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Functions"
      ],
      "metadata": {
        "id": "K40IpAXPjS4I"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def f(x):\n",
        "    y=torch.sin(x)\n",
        "    return y\n",
        "class FCN(nn.Module):\n",
        "    \n",
        "    def __init__(self,layers):\n",
        "        super().__init__() #call __init__ from parent class \n",
        "              \n",
        "        'activation function'\n",
        "        self.activation = nn.Tanh()\n",
        "\n",
        "        'loss function'\n",
        "        self.loss_function = nn.MSELoss(reduction ='mean')\n",
        "    \n",
        "        'Initialise neural network as a list using nn.Modulelist'  \n",
        "        self.linears = nn.ModuleList([nn.Linear(layers[i], layers[i+1]) for i in range(len(layers)-1)])\n",
        "        \n",
        "        self.iter = 0\n",
        "        \n",
        "        'Xavier Normal Initialization'\n",
        "        # std = gain * sqrt(2/(input_dim+output_dim))\n",
        "        for i in range(len(layers)-1):\n",
        "            \n",
        "            # weights from a normal distribution with \n",
        "            # Recommended gain value for tanh = 5/3?\n",
        "            nn.init.xavier_normal_(self.linears[i].weight.data, gain=1.0)\n",
        "            \n",
        "            # set biases to zero\n",
        "            nn.init.zeros_(self.linears[i].bias.data)\n",
        "            \n",
        "    'foward pass'\n",
        "    def forward(self,x):\n",
        "        \n",
        "        if torch.is_tensor(x) != True:         \n",
        "            x = torch.from_numpy(x)                \n",
        "        a = x.float()\n",
        "        for i in range(len(layers)-2):\n",
        "            \n",
        "            z = self.linears[i](a)\n",
        "                        \n",
        "            a = self.activation(z)\n",
        "            \n",
        "        a = self.linears[-1](a)\n",
        "        \n",
        "        return a\n",
        "\n",
        "    def lossNN(self,x,y):\n",
        "      loss_val=self.loss_function(self.forward(x),y)\n",
        "      return loss_val\n",
        "\n",
        "    def closure(self):\n",
        "        \n",
        "        optimizer.zero_grad()\n",
        "        \n",
        "        loss = self.lossNN(x_train, y_train)\n",
        "        \n",
        "        loss.backward()\n",
        "                \n",
        "        self.iter += 1\n",
        "        \n",
        "        if self.iter % 100 == 0:\n",
        "        \n",
        "            print(loss)\n",
        "\n",
        "        return loss   "
      ],
      "metadata": {
        "id": "7EZjlbVMi8w0"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Generate data"
      ],
      "metadata": {
        "id": "pOe9yRvxjakj"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# get the analytical solution over the full domain\n",
        "x = torch.linspace(0,2*np.pi,500).view(-1,1) #prepare to NN\n",
        "y = f(x)\n",
        "print(x.shape, y.shape)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Z1V03CRRjRML",
        "outputId": "6368203b-aaf0-407d-f6ac-ec391a3bf180"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "torch.Size([500, 1]) torch.Size([500, 1])\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "fig, ax1 = plt.subplots()\n",
        "ax1.plot(x.detach().numpy(),y.detach().numpy(),color='blue',label='Real_Train')\n",
        "#ax1.plot(x_train.detach().numpy(),yh.detach().numpy(),color='red',label='Pred_Train')\n",
        "ax1.set_xlabel('x',color='black')\n",
        "ax1.set_ylabel('f(x)',color='black')\n",
        "ax1.tick_params(axis='y', color='black')\n",
        "ax1.legend(loc = 'upper left')"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 296
        },
        "id": "OE4RUZ27p0fT",
        "outputId": "c967427e-9798-4c88-b936-6f247722e526"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x7f3a314926d0>"
            ]
          },
          "metadata": {},
          "execution_count": 100
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "indices=np.arange(500)"
      ],
      "metadata": {
        "id": "K0j21oZxkhdv"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "train_idx,test_idx, _,_ = train_test_split(indices, indices, test_size=0.2, random_state=42)"
      ],
      "metadata": {
        "id": "2Vz3uMrKjda-"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "x_train=x[train_idx]\n",
        "y_train=y[train_idx]\n",
        "x_test=x[test_idx]\n",
        "y_test=y[test_idx]"
      ],
      "metadata": {
        "id": "9fs_BxYokHut"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Train Neural Network"
      ],
      "metadata": {
        "id": "I82eH55ElVSq"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "torch.manual_seed(123)\n",
        "x_train=x_train.float().to(device)\n",
        "y_train=y_train.float().to(device)\n",
        "layers = np.array([1,50,50,20,50,50,1]) #5 hidden layers\n",
        "model = FCN(layers)\n",
        "print(model)\n",
        "model.to(device)\n",
        "params = list(model.parameters())\n",
        "optimizer = torch.optim.Adam(model.parameters(),lr=lr,amsgrad=False)\n",
        "start_time = time.time()"
      ],
      "metadata": {
        "id": "8KZvgKcalOVV",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "9fc6a06e-c367-45a9-b559-7e4fd963ed3c"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "FCN(\n",
            "  (activation): Tanh()\n",
            "  (loss_function): MSELoss()\n",
            "  (linears): ModuleList(\n",
            "    (0): Linear(in_features=1, out_features=50, bias=True)\n",
            "    (1): Linear(in_features=50, out_features=50, bias=True)\n",
            "    (2): Linear(in_features=50, out_features=20, bias=True)\n",
            "    (3): Linear(in_features=20, out_features=50, bias=True)\n",
            "    (4): Linear(in_features=50, out_features=50, bias=True)\n",
            "    (5): Linear(in_features=50, out_features=1, bias=True)\n",
            "  )\n",
            ")\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "for i in range(steps):\n",
        "    optimizer.zero_grad()\n",
        "    yh = model(x_train)\n",
        "    loss = model.lossNN(x_train,y_train)# use mean squared error\n",
        "    loss.backward()\n",
        "    optimizer.step()\n",
        "    if i%(steps/10)==0:\n",
        "      print(loss)"
      ],
      "metadata": {
        "id": "KM3GHnh9ljCh",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "aedf7e9b-d61e-4fa0-89de-4c1fdaba472c"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor(0.6415, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(1.0479e-05, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(6.2135e-06, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(0.0014, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(2.0870e-05, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(3.2861e-05, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(4.3473e-06, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(3.2151e-06, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(1.0634e-05, device='cuda:0', grad_fn=<MseLossBackward0>)\n",
            "tensor(1.5023e-06, device='cuda:0', grad_fn=<MseLossBackward0>)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(model.lossNN(x_test.float().to(device),y_test.float().to(device)))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PyYT4VetZouZ",
        "outputId": "0b64137f-a69a-4b4d-a824-d385312e0f33"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor(7.2382e-06, device='cuda:0', grad_fn=<MseLossBackward0>)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "yh=model(x_train)\n",
        "yh_test=model(x_test.float().to(device))"
      ],
      "metadata": {
        "id": "6kJ3gQ6WYhp9"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "_,indices2=torch.sort(x_train.squeeze(1))\n",
        "_,indices3=torch.sort(x_test.squeeze(1))"
      ],
      "metadata": {
        "id": "QGCG2KHFvInh"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "x_train_plot=x_train[indices2]\n",
        "y_train_plot=y_train[indices2]\n",
        "yh_plot=yh[indices2]\n",
        "x_test_plot=x_test[indices3]\n",
        "y_test_plot=y_test[indices3]\n",
        "yh_test_plot=yh_test[indices3]"
      ],
      "metadata": {
        "id": "udWgFd6mqY7B"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "fig, ax1 = plt.subplots()\n",
        "ax1.plot(x_train_plot.detach().cpu().numpy(),y_train_plot.detach().cpu().numpy(),color='blue',label='Real_Train')\n",
        "ax1.plot(x_train_plot.detach().cpu().numpy(),yh_plot.detach().cpu().numpy(),color='red',label='Pred_Train')\n",
        "#ax1.plot(x_test_plot.detach().numpy(),y_test_plot.detach().numpy(),color='green',label='Real_Test')\n",
        "#ax1.plot(x_test_plot.detach().numpy(),yh_test_plot.detach().numpy(),color='orange',label='Pred_Test')\n",
        "ax1.set_xlabel('x',color='black')\n",
        "ax1.set_ylabel('f(x)',color='black')\n",
        "ax1.tick_params(axis='y', color='black')\n",
        "ax1.legend(loc = 'upper left')"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 296
        },
        "id": "M9YZDGcpodnQ",
        "outputId": "3de051d1-d488-4b4c-947a-510208eeea91"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x7f3a3138a5d0>"
            ]
          },
          "metadata": {},
          "execution_count": 110
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "torch.max(x_train)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "iFZ2_XNKSrQz",
        "outputId": "450d51c5-903a-49be-bcdc-0ffc4b658235"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "tensor(6.2832, device='cuda:0')"
            ]
          },
          "metadata": {},
          "execution_count": 111
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        ""
      ],
      "metadata": {
        "id": "m5fAFnuVT-Z1"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}
